﻿using System.ComponentModel;
using System.Text;
using System.Web.UI;
using JQuery.WebKit.Base;
using JQuery.WebKit.WebCommon;

#region resources
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.css.shCore.css", "text/css", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.css.shCoreDefault.css", "text/css", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.css.shCoreDjango.css", "text/css", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.css.shCoreEclipse.css", "text/css", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.css.shCoreEmacs.css", "text/css", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.css.shCoreFadeToGrey.css", "text/css", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.css.shCoreMDUltra.css", "text/css", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.css.shCoreMidnight.css", "text/css", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.css.shCoreRDark.css", "text/css", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.css.shThemeDefault.css", "text/css", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.css.shThemeDjango.css", "text/css", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.css.shThemeEclipse.css", "text/css", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.css.shThemeEmacs.css", "text/css", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.css.shThemeFadeToGrey.css", "text/css", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.css.shThemeMDUltra.css", "text/css", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.css.shThemeMidnight.css", "text/css", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.css.shThemeRDark.css", "text/css", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.shAutoloader.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.shCore.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.shLegacy.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.brushes.shBrushAppleScript.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.brushes.shBrushAS3.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.brushes.shBrushBash.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.brushes.shBrushColdFusion.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.brushes.shBrushCpp.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.brushes.shBrushCSharp.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.brushes.shBrushCss.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.brushes.shBrushDelphi.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.brushes.shBrushDiff.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.brushes.shBrushErlang.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.brushes.shBrushGroovy.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.brushes.shBrushJava.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.brushes.shBrushJavaFX.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.brushes.shBrushJScript.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.brushes.shBrushPerl.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.brushes.shBrushPhp.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.brushes.shBrushPlain.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.brushes.shBrushPowerShell.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.brushes.shBrushPython.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.brushes.shBrushRuby.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.brushes.shBrushSass.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.brushes.shBrushScala.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.brushes.shBrushSql.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.brushes.shBrushVb.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("UI.WebControls.SyntaxHighlighter.js.brushes.shBrushXml.js", "text/javascript", PerformSubstitution = true)]
#endregion
namespace UI.WebControls
{
    public class SyntaxHighlighter : WebControlBase
    {
        public SyntaxHighlighterBrush Brush { get; set; }
        public SyntaxHighlighterTheme Theme { get; set; }
        public SyntaxHighlighterEnclosingType EnclosingType { get; set; }

        [DefaultValue(true)]
        public bool AutoLinks { get; set; }

        public string ClassName { get; set; }

        public bool Collapse { get; set; }

        [DefaultValue(1)]
        public int FirstLine { get; set; }
        [DefaultValue(true)]
        public bool Gutter { get; set; }

        [DefaultValue(null)]
        public string Highlight { get; set; }
        [DefaultValue(true)]
        public bool HtmlScript { get; set; }

        [DefaultValue(true)]
        public bool SmartTabs { get; set; }

        [DefaultValue(4)]
        public int TabSize { get; set; }

        [DefaultValue(true)]
        public bool Toolbar { get; set; }

        public SyntaxHighlighter()
        {
            this.SetDefaultPropertyValues();
        }

        protected override void OnPreRender(System.EventArgs e)
        {
            WebScriptResource resMain = new WebScriptResource(typeof(SyntaxHighlighter), null, ResourceType.Javascript, "UI.WebControls.SyntaxHighlighter.js.shCore.js");
            WebScriptResource resLegacy = new WebScriptResource(typeof(SyntaxHighlighter), null, ResourceType.Javascript, "UI.WebControls.SyntaxHighlighter.js.shLegacy.js");
            resLegacy.Dependencies.Add(resMain);
            resMain.Dependencies.Add(CommonResources.XRegExp);

            WebScriptResource resBrush = new WebScriptResource(typeof(SyntaxHighlighter), null, ResourceType.Javascript, GetBrushFileResource(Page, Brush));
            WebScriptResource resThemeCore = new WebScriptResource(typeof(SyntaxHighlighter), null, ResourceType.Stylesheet, "UI.WebControls.SyntaxHighlighter.css.shCoreDefault.css");
            WebScriptResource resTheme = new WebScriptResource(typeof(SyntaxHighlighter), null, ResourceType.Stylesheet, GetThemeFileResource(Page, Theme));
            WebScriptResource resInit = new WebScriptResource(typeof(SyntaxHighlighter), null, ResourceType.Javascript, GetInitScript());
            resBrush.Dependencies.Add(resLegacy);
            resThemeCore.Dependencies.Add(resLegacy);
            resTheme.Dependencies.Add(resLegacy);

            Page.Resources.Add(resMain);
            Page.Resources.Add(resLegacy);
            Page.Resources.Add(resBrush);
            Page.Resources.Add(resTheme);
            Page.Resources.Add(resInit);
            base.OnPreRender(e);
        }

        private string GetInitScript()
        {
            StringBuilder sb = new StringBuilder();

            if (!this.IsDefault("AutoLinks")) { sb.AppendFormat("SyntaxHighlighter.defaults['auto-links'] = {0};", AutoLinks.ToString().ToLower()); }
            if (!this.IsDefault("ClassName")) { sb.AppendFormat("SyntaxHighlighter.defaults['class-name'] = '{0}';", ClassName); }
            if (!this.IsDefault("Collapse")) { sb.AppendFormat("SyntaxHighlighter.defaults['collapse'] = {0};", Collapse.ToString().ToLower()); }
            if (!this.IsDefault("FirstLine")) { sb.AppendFormat("SyntaxHighlighter.defaults['first-line'] = {0};", FirstLine); }
            if (!this.IsDefault("Gutter")) { sb.AppendFormat("SyntaxHighlighter.defaults['gutter'] = {0};", Gutter.ToString().ToLower()); }
            if (!this.IsDefault("Highlight")) { sb.AppendFormat("SyntaxHighlighter.defaults['highlight'] = '{0}';", Highlight); }
            if (!this.IsDefault("HtmlScript")) { sb.AppendFormat("SyntaxHighlighter.defaults['html-script'] = {0};", HtmlScript.ToString().ToLower()); }
            if (!this.IsDefault("SmartTabs")) { sb.AppendFormat("SyntaxHighlighter.defaults['smart-tabs'] = {0};", SmartTabs.ToString().ToLower()); }
            if (!this.IsDefault("TabSize")) { sb.AppendFormat("SyntaxHighlighter.defaults['tab-size'] = {0};", TabSize); }
            if (!this.IsDefault("Toolbar")) { sb.AppendFormat("SyntaxHighlighter.defaults['toolbar'] = {0};", Toolbar.ToString().ToLower()); }


            sb.AppendLine("SyntaxHighlighter.all();");

            return sb.ToString();
        }

        protected override void RenderContents(HtmlTextWriter writer)
        {
            string beginTag = string.Format("<script type=\"syntaxhighlighter\" class=\"brush: {0}\"><![CDATA[", GetBrushName(Brush));
            string endTag = "]]></script>";
            if (EnclosingType == SyntaxHighlighterEnclosingType.Pre)
            {
                beginTag = string.Format("<pre class=\"brush: {0}\">", GetBrushName(Brush));
                endTag = "</pre>";
            }
            writer.Write(beginTag);
            base.RenderContents(writer);
            writer.Write(endTag);
        }

        private static string GetBrushName(SyntaxHighlighterBrush brush)
        {
            switch (brush)
            {
                case SyntaxHighlighterBrush.ActionScript3:
                    return "as3";
                case SyntaxHighlighterBrush.BashShell:
                    return "bash";
                case SyntaxHighlighterBrush.ColdFusion:
                    return "cf";
                case SyntaxHighlighterBrush.CSharp:
                    return "csharp";
                case SyntaxHighlighterBrush.CPP:
                    return "cpp";
                case SyntaxHighlighterBrush.CSS:
                    return "css";
                case SyntaxHighlighterBrush.Delphi:
                    return "pas";
                case SyntaxHighlighterBrush.Diff:
                    return "diff";
                case SyntaxHighlighterBrush.Erlang:
                    return "erl";
                case SyntaxHighlighterBrush.Groovy:
                    return "groovy";
                case SyntaxHighlighterBrush.JavaScript:
                    return "js";
                case SyntaxHighlighterBrush.Java:
                    return "java";
                case SyntaxHighlighterBrush.JavaFX:
                    return "jfx";
                case SyntaxHighlighterBrush.Perl:
                    return "perl";
                case SyntaxHighlighterBrush.PHP:
                    return "php";
                case SyntaxHighlighterBrush.PlainText:
                    return "plain";
                case SyntaxHighlighterBrush.PowerShell:
                    return "ps";
                case SyntaxHighlighterBrush.Python:
                    return "py";
                case SyntaxHighlighterBrush.Ruby:
                    return "rails";
                case SyntaxHighlighterBrush.Scala:
                    return "scala";
                case SyntaxHighlighterBrush.SQL:
                    return "sql";
                case SyntaxHighlighterBrush.VisualBasic:
                    return "vb";
                case SyntaxHighlighterBrush.XML:
                    return "xml";
                default:
                    return "plain";
            }
        }

        private static string GetBrushFileResource(Page page, SyntaxHighlighterBrush brush)
        {
            switch (brush)
            {
                case SyntaxHighlighterBrush.ActionScript3:
                    return "UI.WebControls.SyntaxHighlighter.js.brushes.shBrushAS3.js";
                case SyntaxHighlighterBrush.BashShell:
                    return "UI.WebControls.SyntaxHighlighter.js.brushes.shBrushBash.js";
                case SyntaxHighlighterBrush.ColdFusion:
                    return "UI.WebControls.SyntaxHighlighter.js.brushes.shBrushColdFusion.js";
                case SyntaxHighlighterBrush.CSharp:
                    return "UI.WebControls.SyntaxHighlighter.js.brushes.shBrushCSharp.js";
                case SyntaxHighlighterBrush.CPP:
                    return "UI.WebControls.SyntaxHighlighter.js.brushes.shBrushCpp.js";
                case SyntaxHighlighterBrush.CSS:
                    return "UI.WebControls.SyntaxHighlighter.js.brushes.shBrushCss.js";
                case SyntaxHighlighterBrush.Delphi:
                    return "UI.WebControls.SyntaxHighlighter.js.brushes.shBrushDelphi.js";
                case SyntaxHighlighterBrush.Diff:
                    return "UI.WebControls.SyntaxHighlighter.js.brushes.shBrushDiff.js";
                case SyntaxHighlighterBrush.Erlang:
                    return "UI.WebControls.SyntaxHighlighter.js.brushes.shBrushErlang.js";
                case SyntaxHighlighterBrush.Groovy:
                    return "UI.WebControls.SyntaxHighlighter.js.brushes.shBrushGroovy.js";
                case SyntaxHighlighterBrush.JavaScript:
                    return "UI.WebControls.SyntaxHighlighter.js.brushes.shBrushJScript.js";
                case SyntaxHighlighterBrush.Java:
                    return "UI.WebControls.SyntaxHighlighter.js.brushes.shBrushJava.js";
                case SyntaxHighlighterBrush.JavaFX:
                    return "UI.WebControls.SyntaxHighlighter.js.brushes.shBrushJavaFX.js";
                case SyntaxHighlighterBrush.Perl:
                    return "UI.WebControls.SyntaxHighlighter.js.brushes.shBrushPerl.js";
                case SyntaxHighlighterBrush.PHP:
                    return "UI.WebControls.SyntaxHighlighter.js.brushes.shBrushPhp.js";
                case SyntaxHighlighterBrush.PlainText:
                    return "UI.WebControls.SyntaxHighlighter.js.brushes.shBrushPlain.js";
                case SyntaxHighlighterBrush.PowerShell:
                    return "UI.WebControls.SyntaxHighlighter.js.brushes.shBrushPowerShell.js";
                case SyntaxHighlighterBrush.Python:
                    return "UI.WebControls.SyntaxHighlighter.js.brushes.shBrushPython.js";
                case SyntaxHighlighterBrush.Ruby:
                    return "UI.WebControls.SyntaxHighlighter.js.brushes.shBrushRuby.js";
                case SyntaxHighlighterBrush.Scala:
                    return "UI.WebControls.SyntaxHighlighter.js.brushes.shBrushScala.js";
                case SyntaxHighlighterBrush.SQL:
                    return "UI.WebControls.SyntaxHighlighter.js.brushes.shBrushSql.js";
                case SyntaxHighlighterBrush.VisualBasic:
                    return "UI.WebControls.SyntaxHighlighter.js.brushes.shBrushVb.js";
                case SyntaxHighlighterBrush.XML:
                    return "UI.WebControls.SyntaxHighlighter.js.brushes.shBrushXml.js";
                default:
                    return "UI.WebControls.SyntaxHighlighter.js.brushes.shBrushPlain.js";
            }
        }

        private static string GetThemeFileResource(Page page, SyntaxHighlighterTheme theme)
        {
            switch (theme)
            {
                case SyntaxHighlighterTheme.Django:
                    return "UI.WebControls.SyntaxHighlighter.css.shThemeDjango.css";
                case SyntaxHighlighterTheme.Eclipse:
                    return "UI.WebControls.SyntaxHighlighter.css.shThemeEclipse.css";
                case SyntaxHighlighterTheme.Emacs:
                    return "UI.WebControls.SyntaxHighlighter.css.shThemeEmacs.css";
                case SyntaxHighlighterTheme.FadeToGrey:
                    return "UI.WebControls.SyntaxHighlighter.css.shThemeFadeToGrey.css";
                case SyntaxHighlighterTheme.MDUltra:
                    return "UI.WebControls.SyntaxHighlighter.css.shThemeMDUltra.css";
                case SyntaxHighlighterTheme.Midnight:
                    return "UI.WebControls.SyntaxHighlighter.css.shThemeMidnight.css";
                case SyntaxHighlighterTheme.RDark:
                    return "UI.WebControls.SyntaxHighlighter.css.shThemeRDark.css";
                default:
                    return "UI.WebControls.SyntaxHighlighter.css.shCoreDefault.css";
            }
        }
    }
}
